package com.wyiot.pet.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wyiot.core.enums.MessageTypeEnum;
import com.wyiot.core.enums.OrderStatusEnum;
import com.wyiot.pet.mapper.*;
import com.wyiot.pet.model.dto.OrderDTO;
import com.wyiot.pet.model.dto.OrderQueryDTO;
import com.wyiot.pet.model.dto.PetDTO;
import com.wyiot.pet.model.entity.*;
import com.wyiot.pet.model.vo.OrderDetailVO;
import com.wyiot.pet.model.vo.WayBillPetVO;
import com.wyiot.core.exception.ValidateException;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 订单Service
 *
 * @author yly
 * @since 2022年03月31日
 */
@Service
public class OrderService extends ServiceImpl<OrderMapper, OrderDO> {
    @Resource
    WayBillService wayBillService;
    @Resource
    WorkerMapper workerMapper;
    @Resource
    OrderWorkerService orderWorkerService;
    @Resource
    UserMessageService userMessageService;

    /**
     * 创建订单
     *
     * @see OrderDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void creatOrder(OrderDTO orderDTO) {
        OrderDO orderDO = new OrderDO();
        BeanUtils.copyProperties(orderDTO, orderDO);
        orderDO.genOrderNumber();
        save(orderDO);
        ArrayList<WayBillDO> wayBillDOS = new ArrayList<>();
        for (PetDTO pet : orderDTO.getPets()) {
            WayBillDO wayBillDO = new WayBillDO();
            BeanUtils.copyProperties(pet, wayBillDO);
            wayBillDO.setTransportationType(orderDTO.getOrderTransportation());
            wayBillDO.setOrderId(orderDO.getOrderId());
            wayBillDOS.add(wayBillDO);
        }
        wayBillService.saveBatch(wayBillDOS);
    }

    /**
     * 修改订单
     *
     * @see OrderDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void changeOrder(OrderDTO orderDTO) {
        OrderDO orderDO = new OrderDO();
        BeanUtils.copyProperties(orderDTO, orderDO);
        updateById(orderDO);
        List<WayBillDO> wayBillDOS = baseMapper.selectWayBillByOrderId(orderDTO.getOrderId());
        List<WayBillDO> wayBillPetS = new ArrayList<>();
        for (PetDTO pet : orderDTO.getPets()) {
            if (pet.getWayBillId() == null) {
                throw ValidateException.of("操作失敗");
            }
            for (WayBillDO w : wayBillDOS) {
                if (pet.getWayBillId().equals(w.getWayBillId())) {
                    BeanUtils.copyProperties(pet, w);
                    wayBillPetS.add(w);
                }
            }
        }
        wayBillService.updateBatchById(wayBillPetS);
    }

    /**
     * 查询订单详请
     *
     * @param orderId 订单id
     */
    public OrderDetailVO queryOrderDetail(Long orderId) {
        OrderDO orderDO = getById(orderId);
        OrderDetailVO orderDetailVO = new OrderDetailVO();
        BeanUtils.copyProperties(orderDO, orderDetailVO);
        List<WayBillPetVO> wayBillPetVOS = baseMapper.selectWayBillPetByOrderId(orderId);
        orderDetailVO.setWayBillPetVOS(wayBillPetVOS);
        if (orderDetailVO.getOrderTakeMan() != null) {
            WorkerDO workerDO = workerMapper.selectById(orderDetailVO.getOrderTakeMan());
            orderDetailVO.setTakeManName(workerDO.getWorkerName());
            orderDetailVO.setTakeManPhone(workerDO.getWorkerPhone());
        }
        return orderDetailVO;
    }

    /**
     * 取消订单
     *
     * @param orderId 订单id
     */
    public void cancelOrderByOrderId(Long orderId) {
        OrderDO orderDO = baseMapper.selectById(orderId);
        if (orderDO.getOrderState() != OrderStatusEnum.NoPayment) {
            throw ValidateException.of("订单已不能取消");
        }
        baseMapper.changeOrderStateByOrderId(orderId, OrderStatusEnum.IsCancel);
    }

    /**
     * 支付订单
     *
     * @param orderId 订单id
     */
    @Transactional(rollbackFor = Exception.class)
    public void payOrder(Long orderId) {
        OrderDO orderDO = getById(orderId);
        List<WorkerDO> workerDOS = workerMapper.selectList(Wrappers.lambdaQuery(WorkerDO.class).eq(WorkerDO::isIfOnline, true)
                .eq(WorkerDO::getWorkArea, orderDO.getSendAddressCity()));
        WorkerDO workerDO = workerDOS.get(new Random().nextInt(workerDOS.size()));
        /*为订单设置基本信息*/
        orderDO.genTakeCode();
        orderDO.genSerialNumber();
        orderDO.setOrderIspay(true);
        orderDO.setOrderTakeMan(workerDO.getWorkerId());
        orderDO.setOrderState(OrderStatusEnum.WaitForTook);
        orderDO.setPayTime(new Date());
        orderDO.setOrderAmount(10000);
        updateById(orderDO);
        /*订单与工作人员中间表操作*/
        OrderWorkerDO orderWorkerDO = new OrderWorkerDO();
        orderWorkerDO.setOrderId(orderDO.getOrderId());
        orderWorkerDO.setWorkerId(orderDO.getOrderTakeMan());
        orderWorkerService.save(orderWorkerDO);
        /*揽件员发送取件消息*/
        userMessageService.save(new UserMessageDO(orderWorkerDO.getWorkerId(), orderDO.getOrderNumber(),
                true, MessageTypeEnum.NewWorkMessage));
    }

    /**
     * 根据订单号查询订单
     */
    public OrderDO queryOrderByOrderNumber(String number) {

        return baseMapper.selectOrderByOrderNumber(number);
    }

    /**
     * 根据运单号查询订单
     */
    public OrderDO queryOrderByWaybillNumber(String number) {

        return baseMapper.selectOrderByWaybillNumber(number);
    }

    /**
     * 查找订单对应的运单
     */
    public List<WayBillDO> queryWayBillByOrderId(Long orderId) {
        return baseMapper.selectWayBillByOrderId(orderId);
    }


    /**
     * 根据状态查询我寄的订单列表
     *
     * @see OrderQueryDTO
     */
    public Page<OrderDetailVO> querysenderOrders(OrderQueryDTO QueryDTO, Long userId) {
        Set<Integer> list = new HashSet<>();
        Integer[] state = {OrderStatusEnum.WaitForTook.getCode(), OrderStatusEnum.WaitForSign.getCode(), OrderStatusEnum.NoPayment.getCode()};
        Collections.addAll(list, state);
        if (QueryDTO.getState() == null || list.contains(QueryDTO.getState())) {
            return baseMapper.selectOrdersByUserIdAndCode(Page.of(QueryDTO.getPageNum(), QueryDTO.getPageSize()), userId, QueryDTO.getState());
        }
        return baseMapper.selectOtherOrder(Page.of(QueryDTO.getPageNum(), QueryDTO.getPageSize()), userId);
    }

    /**
     * 根据状态查询我收的订单列表
     *
     * @see OrderQueryDTO
     */
    public Page<OrderDetailVO> querytakerOrders(OrderQueryDTO QueryDTO, String phone) {
        Set<Integer> list = new HashSet<>();
        Integer[] state = {OrderStatusEnum.WaitForSign.getCode(), OrderStatusEnum.IsFinish.getCode()};
        Collections.addAll(list, state);
        if (list.contains(QueryDTO.getState()) || QueryDTO.getState() == null) {
            return baseMapper.selectOrdersByPhoneAndState(Page.of(QueryDTO.getPageNum(), QueryDTO.getPageSize()), phone, QueryDTO.getState());
        }
        return null;
    }

}